package org.doxla.oomwatch.observerable;

import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.apache.log4j.Logger;

/**
 * An {@link Observable} that notifies Observers when the VM memory usage raises above
 * the threshhold value.
 * 
 * @author danoxlade
 *
 */
public abstract class AbstractOomWatcher extends Observable {
	
	private static final Logger logger = Logger.getLogger(AbstractOomWatcher.class);
	
	private long threshold = 0L;

	public AbstractOomWatcher() {
		super();
	}
	
	public AbstractOomWatcher(List<OomObserver> oomObservers, long threshold) {
		super();
		setOomObservers(oomObservers);
		setThreshold(threshold);
	}
	
	/**
	 * Utility method
	 * @param oomObservers
	 */
	public void setOomObservers(List<OomObserver> oomObservers){
		for(OomObserver o : oomObservers){
			addObserver(o);
		}
	}

	/**
	 * @param threshold the threshold to set
	 */
	public void setThreshold(long threshold) {
		this.threshold = threshold;
	}
	
	/**
	 * Subclasses should implement how the threshold is exceeded in terms
	 * of the Runtime. Typically this would be something like current memory
	 * usage greater than the threshold or max memory - current usage less
	 * than the threshold for example.
	 * 
	 * @return true if the threshold value has been exceeded in a way such that
	 * any {@link Observer}s should be notified.
	 */
	public abstract boolean thresholdExceeded();
	
	public void doCheck(){
		synchronized (logger) {
			if(thresholdExceeded()){
				setChanged();
				notifyObservers();
			}
		}
	}

	/**
	 * @return the threshold
	 */
	public long getThreshold() {
		return threshold;
	}

}
